/* Copyright 2014 Jan Wolter */
#include "stack.h"
#include "stock.h"
#include "found.h"
#include "waste.h"
#include "solve.h"
#include "game.h"

char *gamename= "Captive Queens";
char *gameopt= "";
Stack *gathered= NULL;
Stack *temp= NULL;

int f1passes, f2passes, f3passes;
int nplayed= 0;
int nwon= 0;
int cardsleft= 0;

void setopt(char c) {}

/* This is the main program for setting up the current game */
void exec(int gather, int arif, int over, int cut)
{
    /* Could set things like ndeck, nsuit here */

    /* Build and shuffle the deck */
    Stack *shuf= mixcards(arif, over, cut);

    /* Create the foundations */
    for (int s= 0; s < nsuit; s++)
    {
	makeFound(12, s, 0, 1);
	makeFound(5, s, -1, 6);
	makeFound(6, s, +1, 6);
    }
    f1passes= f2passes= f3passes= 0;

    /* Create the waste */
    makeWaste();

    /* Create the stock */
    makeStock(DT_WASTE, 1,3,shuf);

    freeStack(shuf);

    if (verbose > 1) printState(stdout, stacks);

    int win= solve(gather,0);
    nplayed++;
    cardsleft+= stacks[waste[0].id].n;
    if (win) nwon++;

    if (verbose > 0) printf("Queens=%d Fives=%d Sixes=%d Left=%d\n",
	    f1passes, f2passes, f3passes, stacks[waste[0].id].n);

    cleanFound();
    cleanWaste();
    cleanStock();
    cleanStacks();
}

void gatherAll()
{
    if (gathered == NULL)
	gathered= allocStack(ncard);
    else
	gathered->n= 0;

    /* Don't need to gather the stock because it is always empty */
    gatherFound(gathered);
    gatherWaste(gathered, 0);
}

void printState(FILE *f, Stack *stks)
{
    printStock(f, stks);
    printWaste(f, stks);
    printFound(f, stks);
}

/* Is the kth foundation set done?
 *   k=0 queens
 *   k=1 fives
 *   k=2 sixes
 */
int fdone(int k)
{
    for (int i= k; i < 12; i+= 3)
	if (stacks[foundation[i].id].n < foundation[i].maxsize)
	    return 0;
    return 1;
}

int victory()
{
    if (f1passes == 0 && fdone(0)) f1passes= passcnt;
    if (f2passes == 0 && fdone(1)) f2passes= passcnt;
    if (f3passes == 0 && fdone(2)) f3passes= passcnt;
    return (nOff() == ncard);
}

/* Return a quality rating for the current solution. Bigger is better. Usually
 * it's just cards off. This is used to decide which solution to report in
 * cases where we never win.
 */
int quality()
{
    return nOff();
}


void summary()
{
    printf("Played:     %d games\n",nplayed);
    printf("Won:        %d games (%.2f%)\n",nwon,(float)nwon*100/nplayed);
    printf("Cards Left: %.2f\n",(float)cardsleft/nplayed);
}
